home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-05-25 | 13.6 KB | 245 lines | [04] ASCII Text (0x0000) |
- *******************************************************************************
- *
- * fakeModalDialog and other supporting access routines and such.
- * Version 3.0
- *
- * Copyright (c)
- * Apple Computer, Inc. 1989-1990
- * All Rights Reserved.
- *
- * Written by Eric Soldan.
- *
- * Developer Technical Support Apple II Sample Code
- *
- * The purpose of this code is to handle dialogs in a variety of ways
- * that are more robust than what the toolbox offers. It also supports
- * the new movable/modeless dialog types described in the latest human
- * interface guidelines.
- *
- *******************************************************************************
- *
- * Here is some C sample code that uses fakeModalDialog. This code is
- * for an about box. What is different about this about box is that
- * you can use menus while the about box is on the screen. This means
- * that you can use desk accessories while the about box is active.
- * It also means that you can quit the application at this time.
- * You can also close the about box with the close menu option.
- *
- * This sample uses the modal mode with menus for the about box. Since
- * menus are available, there is more support (code) necessary from the
- * application. The application has to detect that the user chose
- * close from the menu and take appropriate action, for example.
- *
- * First, a little about fakeModalDialog:
- *
- * fakeModalDialog returns a long as a result.
- * If the result is NULL:
- * Nothing happened. Unlike ModalDialog, control is returned to
- * the application during null events. This is so the application
- * can do stuff like switch cursors, or other idle tasks.
- * If bit 31 of the result is true:
- * The user chose a menu item. Bits 0-15 are the menu item ID.
- * Bits 16-30 are the menu ID.
- * If bit 31 of the result is false:
- * The user clicked on a control. Bits 0-30 are the control ID.
-
- * Now, the sample code fragment:
-
- * #define aboutBoxID 0x1001L
- *
- * void doAboutBox()
- * {
- * WindowPtr wptr, keepPort;
- * unsigned long id;
- * unsigned int item;
- * keepPort = GetPort(); /* Preserve the current port. */
- *
- * wptr = NewWindow2(NULL, NULL, NULL, NULL, 2, aboutBoxID, rWindParam1);
- * /* Open the about box from a resource. */
- *
- * if (!_toolErr) { /* If the window opened successfully... */
- * aboutWindow = wptr; /* Set the aboutWindow global variable. */
- * /* This tells other routines what state */
- * /* we are in. */
- *
- * for (;;) { /* Loop, due to NULL events being returned. */
- *
- * id = fakeModalDialog(
- * &event, /* Pointer to extended event record. */
- * NULL, /* Use default update procedure. */
- * NULL, /* There will be no event mods. */
- * NULL, /* Do standard beep. */
- * fmdMenuSelect+ /* Allow pullDowns. */
- * fmdMenuKey+ /* Allow menu keys. */
- * fmdDeskAcc+ /* Allow desk accessories. */
- * fmdUpdateAll /* Update all windows, not just about. */
- * );
- *
- * item = id; /* Get lo-word from result. */
- *
- * if (id & 0x80000000L) { /* If menu command... */
- * if (item == 255) { /* If close command then */
- * HiliteMenu(0, FileMenuID); /* turn menu inv. off. */
- * break; /* Go close about box. */
- * }
- * doMenuCommand(id); /* Do other menus (like quit). */
- * if (quitFlag) break; /* User did do a quit from menu. */
- * }
- * else { /* ...else handle controls. */
- * if (item == 1) break; /* User clicked OK button. */
- * }
- * }
- *
- * SetPort(keepPort); /* Put port back before closing about. */
- * CloseWindow(wptr); /* Close aboutBox. */
- * aboutWindow = NULL; /* Let others know it is closed. */
- * appSetMenus(); /* Update the menus to reflect a new. */
- * } /* top window. */
- * }
-
- * An interesting point here is the call to appSetMenus. This is a routine
- * in the application that is responsible for putting the menus in the
- * correct state. fakeModalDialog automatically calls this routine (if told
- * to) whenever an activate event occurs that it gets a chance to see.
- * fakeModalDialog may not see the activate event only if a desk accessory
- * is open, just behind the about box. When the about box is closed, the
- * desk accessory gets the activate event. fakeModalDialog never got an
- * activate event, so it didn't know to call the menu update routine. This
- * situation can only occur when a desk accessory is just behind the window
- * to be closed. As a safe rule, whenever a window is closed, the menu
- * update routine should be called by the application. (Something like this
- * should be done anyway.)
-
- * To tell fakeModalDialog to automatically call a menu update routine when
- * it gets an activate event, make a call to fmdSetMenuProc. For an application
- * menu update routine called appSetMenus, you would tell fakeModalDialog
- * about it by the following:
- * fmdSetMenuProc(appSetMenus);
- * To turn off menu updating again, do this:
- * fmdSetMenuProc(NULL);
-
- * fmdEditMenu figures the state of cut, copy, paste, and clear in
- * the edit menu based on the state of controls in the window.
- * It looks up the target control (either lineEdit or textEdit) and
- * then sets the states appropriately. For lineEdit, if anything
- * is selected, then cut, copy and clear are available. If there is
- * anything in the scrap, then paste is also available. TextEdit
- * works the same way, unless the textEdit control is a read-only
- * control. In that case, cut, paste, and clear are not available.
- * If there is no lineEdit or textEdit control, then the state of
- * these menu items is left alone. The application needs to take care
- * of them in that case. (It is possible that there are custom
- * controls for the application that can use these menu items, and
- * there is no way for fakeModalDialog to know about them. Therefore
- * the correct thing to do is to do nothing.)
-
- * fmdFindCursorCtl is used to find which control is at a certain point.
- * The toolbox call FindControl can't be used for this because textEdit
- * controls become active when called with a point in them. That is not
- * the desired effect of fmdFindCursorCtl. If you just want to know what
- * control you are over and have nothing affected, then use this entry
- * point. It is used by fakeModalDialog to determine whether or not to
- * display an i-beam cursor. If the i-beam bit is set and the user moves
- * the mouse over a lineEdit or textEdit control, then the cursor changes
- * to an i-beam. Note that the scrollbars for a textEdit control are
- * considered a separate control. This is so that the cursor stays
- * an arrow when over the scrollbars.
-
- * Back to fakeModalDialog:
-
- * Some sample calls (in C) would look like:
- * ctlID = fakeModalDialog(&event, NULL, NULL, NULL, 0);
- * ctlID = fakeModalDialog(&event, updateProc, NULL, -1L, 0);
- * ctlID = fakeModalDialog(&event, updateProc, eventHook, beepProc, flags);
- *
- * The parameters are:
- *
- * event: A pointer to an extended (for 5.0) event record.
- * updateProc: Pointer to function to update the window. Pass a NULL for
- * default. (The default entry point is called fmdStdDrawProc.)
- * eventHook: Pointer to function that is called after the GetNextEvent
- * call and before any processing occurs on that event. This
- * is more useful than a filter. You can simply change the
- * event by changing the event record. For example: Let's say
- * that you want to be able to cancel a modal dialog by pressing
- * either openApple-period or ESC. The problem is that,
- * although you can have two key equivalents for a
- * super-control, theway that modifiers are determined is the
- * same for both keys. This means that you can't have
- * openApple-period and ESC asyour two key equivalents. With
- * this event hook, you can lookat the event, and if it is the
- * openApple-period, you can simply change the event record so
- * that it is an ESC with no openApple modifier. Then when you
- * return to fakeModalDialog, it will handle the event as if the
- * user simply typed an ESC. By using this technique, you can
- * have as many modifiers as you want. If you wish to filter
- * out an event, you would simply changethe event type to a
- * NULL event.
- * beepProc: Pointer to custom beep function. fakeModalDialog calls this
- * if there is any mouseDown outside the window, just like
- * ModalDialog.If you wish it to beep like ModalDialog, pass a
- * NULL. If you wish it to do nothing, pass a -1.
- * If you wish a custom beep function, pass it a pointer to
- * that function.
- * flags, bit 0: Cut/Copy/Paste for lineEdit items would normally involve
- * the scrap. When this bit is true, the scrap is not involved
- * when using lineEdit items. This may be useful to protect a
- * large scrap for an application from being hit with something
- * trivial.
- * bit 1: If true, allow menu pullDowns for movable/modal dialogs.
- * If they are allowed, then the return value is the menu
- * item ID (low-word) and the menu ID (hi-word). To
- * distinguish from ctlID's, thehi-bit (bit 31) is set. This
- * means that if you are allowing menu selections, you can't have
- * any menu ID's with a hi-bit-on ID. It also means that you
- * can't have controls with bit 31 on either.
- * bit 2: If true, allow menu keys. Return values work the same as for
- * pullDowns.
- * bit 3: If true, use i-beam cursor for lineEdit & textEdit ctls.
- * Otherwise, use an arrow cursor everywhere.
- * bit 4: If true, automatically handle desk accessories. This means
- * that bit 1 must be true to have fakeModalDialog open the DA.
- * If the DA is already open, the user can click on it, and it
- * will become active, even if bit 1 is false.
- * bit 14: If true, update all windows. The toolbox call ModalDialog
- * does not update other windows. This takes away a lot of the
- * point of movable/modal dialogs. The whole point is so that
- * you can see what is behind it. When you move the dialog, if
- * the windows in back didn't update, then there would be no
- * point in moving the window. If you want, you can set this
- * bit false, and it will update only the front-most
- * application window.
- * bit 15: This is the bit that determines whether or not a dialog is
- * movable. If it is true, then the dialog is movable. To be
- * moved, however, it has to have a title bar (the drag region)
- * and it has to have the fMove bit set. Without these also,
- * the window still won't be able to be moved.
- *
- * ctlID: Control that was hit, or menu that was chosen.
- * bit 31 off, it is a control ID.
- * bit 31 on, it is a menu ID (hi-word), menu item ID (lo-word).
- *
- * There is one more thing to worry about, and that is the border of the window.
- * The window manager doesn't allow you have an alert frame and a title at the
- * same time. If you set both of these bits in the wFrameBits field, then the
- * alert border is drawn wrong. It would be ideal for fakeModalDialog if this
- * restriction didn't exist. Then the window attributes all could be chosen via
- * the window frame bits in a resource. Unfortunately, this isn't the case. To
- * manage this restriction, the default update procedure, under certain
- * conditions, draws the alert frame itself. If fAlert is set, then the alert
- * border isn't drawn by the default update procedure. The update procedure
- * doesn't have to draw it, since it is automatically drawn by the window
- * manager. If fAlert is set, then the dialog doesn't have a title bar, due to
- * the window manager restriction. If fAlert isn't set, then the default update
- * procedure draws the alert border. The alert border is drawn as part of the
- * content of the window. Due to this, the coordinates you use for the content
- * of the window have to be a little different, to make space for the border.
- * The upper-left-hand corner of the window is really 10,4, (4,4 for 320 mode)
- * instead of 0,0. So far, we have discussed how the alert border gets drawn,
- * either by the window manager, or by the default update procedure for
- * fakeModalDialog. It is possible that you don't want an alert border at all.
- * If you don't, then fAlert should be off, and you should turn on fFlex. fFlex
- * was used because it should be able to be set from a resource, and all other
- * bits would have an adverse effect. Dialogs don't have grow boxes and zoom
- * boxes, so fFlex is meaningless for dialogs (until now).
-